import axios, { AxiosError, AxiosRequestConfig } from "axios";
import useAuthStore from "@/store/modules/auth";
import { ILoginRes } from "@/types";

const instance = axios.create({
  //基础路径上会携带/api-servce
  baseURL: "/api",
  timeout: 15000,
});

interface PendingTask {
  config: AxiosRequestConfig;
  resolve: Function;
}
let refreshing = false;
const quere: PendingTask[] = [];
// 添加请求拦截器
instance.interceptors.request.use(
  config => {
    const authStore = useAuthStore();
    let { access_token } = authStore.tokenObj;
    if (access_token) {
      config.headers = config.headers || {};
      config.headers.Authorization = `Bearer ${access_token}`;
    }
    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  }
);

// 添加响应拦截器
instance.interceptors.response.use(
  response => {
    return response.data;
  },
  async (
    error: AxiosError<
      {
        success: boolean;
        status: number;
        data: any;
        path: string;
        [k: string]: any;
      },
      any
    >
  ) => {
    let { data, config } = error.response!;
    if (refreshing) {
      return new Promise(resolve => {
        quere.push({
          config,
          resolve,
        });
      });
    }

    if (data.status === 401 && !config.url?.includes("/refresh")) {
      refreshing = true;
      const res = await refreshToken();
      if (res.code === 200) {
        quere.forEach(({ config, resolve }) => resolve(instance(config)));
        return instance(config);
      } else {
        alert(data || "登录过期，请重新登录");
      }
    }

    if (error && error.response) {
      switch (error.response.status) {
        case 400:
          error.message = "请求错误";
          break;
        case 401:
          error.message = "未授权，请登录";
          break;
        case 403:
          error.message = "拒绝访问";
          break;
        case 404:
          error.message = `请求地址出错: ${error.response.config.url}`;
          break;
        case 408:
          error.message = "请求超时";
          break;
        case 500:
          error.message = "服务器内部错误";
          break;
        case 501:
          error.message = "服务未实现";
          break;
        case 502:
          error.message = "网关错误";
          break;
        case 503:
          error.message = "服务不可用";
          break;
        case 504:
          error.message = "网关超时";
          break;
        default:
          error.message = "网络异常，请稍后再试";
          break;
      }
    }

    //可以对错误信息进行集中操作，统一管理
    return Promise.reject(error);
  }
);

const refreshApi = async (data: string): Promise<ILoginRes> =>
  await instance.get("/auth/refresh", { params: { token: data } });

const refreshToken = async () => {
  const authStore = useAuthStore();
  const { refresh_token } = authStore.tokenObj;
  const res = await refreshApi(refresh_token);
  if (res.code === 200) {
    authStore.saveToken(res.data);
  }
  return res;
};
export default instance;
